#include "student.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
#include <sstream>
#include <cstring>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <thread>
#include <mutex>
#include <mysql/mysql.h>

using namespace std;

mutex mtx;
const int MAX_STUDENTS = 1000;

const char *host = "localhost";
const char *user = "Lishixian";
const char *password = "123456";
const char *database = "Student";

MYSQL *mysql_init_connection() {
    MYSQL *conn = mysql_init(nullptr);
    if (conn == nullptr) {
        cerr << "初始化MySQL连接失败" << endl;
        exit(EXIT_FAILURE);
    }
    if (!mysql_real_connect(conn, host, user, password, database, 0, nullptr, 0)) {
        cerr << "连接到MySQL数据库失败: " << mysql_error(conn) << endl;
        mysql_close(conn);
        exit(EXIT_FAILURE);
    }
    return conn;
}

void insert_student_data(MYSQL *conn, const student &s, const string &table_name) {
    string query = "INSERT INTO " + table_name + " (name, number, grade, hobby1, hobby2, hobby3) VALUES ('" + s.name + "', " + to_string(s.number) + ", " + to_string(s.grade) + ", '" + s.hobby[0] + "', '" + s.hobby[1] + "', '" + s.hobby[2] + "')";
    if (mysql_query(conn, query.c_str())) {
        cerr << "插入数据失败: " << mysql_error(conn) << endl;
        mysql_close(conn);
        exit(EXIT_FAILURE);
    }
}
string generate_table_name() {
    time_t now = time(nullptr);
    char buffer[80];
    strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", localtime(&now));
    string table_name = "Students_" + string(buffer);
    return table_name;
}


void create_table(MYSQL *conn, const string &table_name) {
    string query = "CREATE TABLE " + table_name + " (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), number BIGINT, grade INT, hobby1 VARCHAR(255), hobby2 VARCHAR(255), hobby3 VARCHAR(255))";
    if (mysql_query(conn, query.c_str())) {
        cerr << "创建表失败: " << mysql_error(conn) << endl;
        mysql_close(conn);
        exit(EXIT_FAILURE);
    }
}

bool table_exists(MYSQL *conn, const string &table_name) {
    string query = "SHOW TABLES LIKE '" + table_name + "'";
    if (mysql_query(conn, query.c_str())) {
        cerr << "查询表失败: " << mysql_error(conn) << endl;
        mysql_close(conn);
        exit(EXIT_FAILURE);
    }
    MYSQL_RES *result = mysql_store_result(conn);
    if (result == nullptr) {
        cerr << "获取查询结果失败: " << mysql_error(conn) << endl;
        mysql_close(conn);
        exit(EXIT_FAILURE);
    }
    bool exists = mysql_num_rows(result) > 0;
    mysql_free_result(result);
    return exists;
}

void handle_connection(int client_sock) {
    try {
        while (true) {
            char data[1024];
            int bytes_read = read(client_sock, data, sizeof(data));
            if (bytes_read <= 0) {
                break;
            }

            istringstream ss(string(data, bytes_read));
            string name, number, grade, hobby1, hobby2, hobby3;
            getline(ss, name, ',');
            getline(ss, number, ',');
            getline(ss, grade, ',');
            getline(ss, hobby1, ',');
            getline(ss, hobby2, ',');
            getline(ss, hobby3, '\n');

            student s;
            s.name = name;
            try {
                s.number = stol(number);
                s.grade = stol(grade);
            } catch (const std::invalid_argument& e) {
                cerr << "无效的数字输入: " << e.what() << endl;
                continue;
            }

            s.hobby = {hobby1, hobby2, hobby3};

            unique_lock<mutex> lock(mtx);
            MYSQL *conn = mysql_init_connection();

            static int inserted_count = 0;
            static string current_table_name = generate_table_name();

            if (inserted_count >= MAX_STUDENTS) {
                // 超过了最大学生数量，创建新表
                current_table_name = generate_table_name();
                create_table(conn, current_table_name);
                inserted_count = 0;
            } else if (!table_exists(conn, current_table_name)) {
                // 当前表不存在，创建表
                create_table(conn, current_table_name);
            }

            insert_student_data(conn, s, current_table_name);
            mysql_close(conn);
            inserted_count++;
        }
    } catch (exception& e) {
        cerr << "线程中发生异常: " << e.what() << "\n";
    }
    close(client_sock);
}
void start_server(short port) {
    int server_fd;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        cerr << "创建套接字失败" << endl;
        exit(EXIT_FAILURE);
    }
    
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
        cerr << "设置套接字选项失败" << endl;
        close(server_fd);
        exit(EXIT_FAILURE);
    }
    
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(port);
    
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        cerr << "绑定套接字失败" << endl;
        close(server_fd);
        exit(EXIT_FAILURE);
    }
    
    if (listen(server_fd, 3) < 0) {
        cerr << "监听套接字失败" << endl;
        close(server_fd);
        exit(EXIT_FAILURE);
    }
    
    while (true) {
        int client_sock;
        if ((client_sock = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
            cerr << "接受连接失败" << endl;
            continue; // 继续等待下一个连接
        }
        thread(handle_connection, client_sock).detach();
    }
}
int main() {
    // 启动两个服务器线程，分别监听不同的端口
    thread t1(start_server, 12345);
    thread t2(start_server, 12346);
    t1.join();
    t2.join();
    return 0;
}